/*
 * @Author: your name
 * @Date: 2021-02-23 21:50:56
 * @LastEditTime: 2021-02-23 22:14:36
 * @LastEditors: your name
 * @Description: In User Settings Edit
 * @FilePath: \learn-fe\hand-write\src\handWrite\asyncLimit.js
 */
// function asyncLimit(maxNumber, urls, generatePromise) {
//   let tasks = [];
//   let runningTasks = [];
//   let i = 0;

//   function excute() {
//     // 处理边界问题
//     if (i === urls.length) {
//       return Promise.resolve();
//     }

//     let task = Promise.resolve().then(() => generatePromise(urls[i++]));
//     tasks.push(task);

//     let p = task.then(() => {
//       runningTasks.splice(runningTasks.indexOf(p), 1);
//     });
//     runningTasks.push(p);

//     let result = Promise.resolve();

//     if (runningTasks.length >= maxNumber) {
//       result = Promise.race(runningTasks);
//     }
//     // 递归执行，直到处理完
//     return result.then(() => excute());
//   }

//   return excute().then(() => Promise.all(tasks));
// }

// function timeout(i) {
//   return new Promise((resolve, reject) => {
//     console.log(i);
//     setTimeout(() => {
//       resolve(i);
//     }, i);
//   });
// }

// const data = Date.now();
// asyncLimit(2, [1000, 5000, 3000, 2000], timeout).then((results) => {
//   console.log(results);
//   console.log(Date.now() - data); // 6s
// });

function asyncLimit(maxNumber, promises) {
  let tasks = [];
  let runningTasks = [];
  let index = 0;
  function excute() {
    // 边界处理，已完成了
    if (index === promises.length) {
      return Promise.resolve();
    }
    let task = promises[index++];
    let TrueTask = Promise.resolve().then(() => {
      task();
    });
    tasks.push(TrueTask);

    const p = TrueTask.then(() => {
      runningTasks.splice(runningTasks.indexOf(p), 1);
    });

    runningTasks.push(p);
    let result = Promise.resolve();

    if (runningTasks.length >= maxNumber) {
      result = Promise.race(runningTasks);
    }

    return result.then(() => {
      excute();
    });
  }

  return excute().then(() => Promise.all(taks));
}
